package com.ztgf.message.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.CustomizeUtil;
import com.ztgf.message.common.config.YmlConfig;
import com.ztgf.message.mapper.MessageNoticeMapper;
import com.ztgf.message.model.bo.MessageNoticeBO;
import com.ztgf.message.model.bo.MessageNoticeSaveBO;
import com.ztgf.message.model.dto.MessageNoticeDTO;
import com.ztgf.message.model.service.IMessageNoticeService;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.service.ISysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 通知消息控制器
 *
 * @author YUE
 * @Date 2020-05-28 16:21:07
 */
@DubboService
public class MessageNoticeServiceImpl extends ServiceImpl<MessageNoticeMapper, MessageNoticeDTO> implements IMessageNoticeService {

    @Resource
    private YmlConfig ymlConfig;

    @Autowired
    private MessageNoticeMapper messageNoticeMapper;

    @DubboReference
    private ISysUserService sysUserService;

    /**
     * 更新所有消息为不置顶
     */
    @Override
    public void updateAllMessageNoticeNotTop() {
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq("is_top", 0);
        MessageNoticeDTO messageNoticeDTO = new MessageNoticeDTO();
        messageNoticeDTO.setIsTop(1);
        update(messageNoticeDTO, wrapper);
    }

    @Override
    public boolean add(MessageNoticeSaveBO saveBO, String sessionId) {
        SysUserDTO sysUserDTO = sysUserService.getUserBySessionId(sessionId);
        MessageNoticeDTO dto = new MessageNoticeDTO();
        BeanUtils.copyProperties(saveBO, dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        dto.setPublisherId(sysUserDTO.getId());
        dto.setPublisherName(sysUserDTO.getName());
//        int i = selectCount(new EntityWrapper<>());
        Integer i = baseMapper.getMaxSort();
        dto.setSort(i + 1);
        return this.insert(dto);
    }

    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    public boolean deletePhById(Long id) {
        return messageNoticeMapper.deletePhById(id);
    }

    /**
     * 消息恢复
     *
     * @param id
     * @return
     */
    @Override
    public boolean recoverPhById(Long id) {
        MessageNoticeDTO messageNoticeDTO = new MessageNoticeDTO();
        messageNoticeDTO.setId(id);
        messageNoticeDTO.setDeleted(0);
        messageNoticeMapper.updateById(messageNoticeDTO);
        return true;
    }

    /**
     * 根据相关信息查找  有页码
     *
     * @param messageNoticeBO
     * @return
     */
    @Override
    public Page<MessageNoticeDTO> getBySelectNoticeInfoPage(MessageNoticeBO messageNoticeBO) {
        messageNoticeBO = addMustData(messageNoticeBO);
        Wrapper<MessageNoticeDTO> wrapper = getBySelectNoticeInfo(messageNoticeBO);
        return selectPage(new Page<>(messageNoticeBO.getPageNo(), messageNoticeBO.getPageSize()), wrapper);
    }

    /**
     * 把消息设置为软删除
     *
     * @param ids
     */
    @Override
    public void updateMessageDeleteByIds(List<String> ids) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.in("id", ids);
        MessageNoticeDTO messageNoticeDTO = new MessageNoticeDTO();
        messageNoticeDTO.setDeleted(1);
        update(messageNoticeDTO, wrapper);
    }

    @Override
    public Result<?> updateSort(Long id, Integer sort) {
        // sort:0上，1下
        MessageNoticeDTO dto = this.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_COMMODITY_ERROR_340000);
        }
        // 原来的序号
        Integer dtoSort = dto.getSort();
        // 要更改的序号
        Integer number;
        if (sort.equals(0)) {
            // 最小排序号
            Integer minSort = baseMapper.getMinSort();
            if (dtoSort.equals(minSort)) {
                return new Result<>(CodeEnum.SORT_FAIL);
            }
            // 获取小于当前序号的前一位
            Wrapper<MessageNoticeDTO> smallWrapper = new EntityWrapper<>();
            smallWrapper.eq("type", 0);
            smallWrapper.eq("status", 0);
            smallWrapper.eq("deleted", 0);
            smallWrapper.lt("sort", dtoSort);
            smallWrapper.orderBy("sort", false);
            MessageNoticeDTO smallDto = this.selectOne(smallWrapper);
            number = smallDto.getSort();
            MessageNoticeDTO updateSmall = new MessageNoticeDTO();
            updateSmall.setId(smallDto.getId());
            updateSmall.setSort(dtoSort);
            updateSmall.setUpdateTime(new Date());
            this.updateById(updateSmall);
        } else {
            // 最大排序号
            Integer maxSort = baseMapper.getMaxSort();
            if (dtoSort.equals(maxSort)) {
                return new Result<>(CodeEnum.SORT_FAIL_A);
            }
            // 获取当前大一位的数据
            Wrapper<MessageNoticeDTO> maxWrapper = new EntityWrapper<>();
            maxWrapper.eq("type", 0);
            maxWrapper.eq("status", 0);
            maxWrapper.eq("deleted", 0);
            maxWrapper.gt("sort", dtoSort);
            maxWrapper.orderBy("sort", true);
            MessageNoticeDTO maxDto = this.selectOne(maxWrapper);
            number = maxDto.getSort();
            MessageNoticeDTO updateMax = new MessageNoticeDTO();
            updateMax.setId(maxDto.getId());
            updateMax.setSort(dtoSort);
            updateMax.setUpdateTime(new Date());
            this.updateById(updateMax);
        }
        MessageNoticeDTO updateDto = new MessageNoticeDTO();
        updateDto.setId(dto.getId());
        updateDto.setSort(number);
        updateDto.setUpdateTime(new Date());
        boolean update = this.updateById(updateDto);
        if (!update) {
            return new Result<>(CodeEnum.FAIL);
        }
        return new Result<>(CodeEnum.SUCCESS);
    }

    @Override
    public Result<?> updateIsTop(Long id) {
        MessageNoticeDTO dto = this.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_COMMODITY_ERROR_340000);
        }
        MessageNoticeDTO updateDto = new MessageNoticeDTO();
        updateDto.setId(dto.getId());
        if (dto.getIsTop().equals(0)) {
            updateDto.setIsTop(1);
        } else {
            updateDto.setIsTop(0);
        }
        boolean update = this.updateById(updateDto);
        if (!update) {
            return new Result<>(CodeEnum.FAIL);
        }
        return new Result<>(CodeEnum.SUCCESS);
    }

    @Override
    public Result<?> updateIsHot(Long id) {
        MessageNoticeDTO dto = this.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_COMMODITY_ERROR_340000);
        }
        MessageNoticeDTO updateDto = new MessageNoticeDTO();
        updateDto.setId(dto.getId());
        updateDto.setUpdateTime(new Date());
        if (dto.getIsHot().equals(0)) {
            updateDto.setIsHot(1);
        } else {
            updateDto.setIsHot(0);
        }
        boolean update = this.updateById(updateDto);
        if (!update) {
            return new Result<>(CodeEnum.FAIL);
        }
        return new Result<>(CodeEnum.SUCCESS);
    }

    @Override
    public boolean updateHideFromView(Long id) {
        MessageNoticeDTO dto = this.selectById(id);
        if (dto == null) {
            return false;
        }
        MessageNoticeDTO updateDto = new MessageNoticeDTO();
        updateDto.setId(dto.getId());
        if (dto.getIsPublish().equals(0)) {
            updateDto.setIsPublish(1);
        } else {
            updateDto.setIsPublish(0);
        }
        updateDto.setUpdateTime(new Date());
        return this.updateById(updateDto);
    }

    /**
     * 添加必要数据
     *
     * @param epgNoticeBO
     * @return
     */
    private MessageNoticeBO addMustData(MessageNoticeBO epgNoticeBO) {
        epgNoticeBO.setStatus(0);//正常消息
        epgNoticeBO.setIsPublish(1);//发布
        return epgNoticeBO;
    }

    /**
     * 根据相关信息查找  无页码
     *
     * @param messageNoticeBO
     * @return
     */
    @Override
    public List<MessageNoticeDTO> getBySelectNoticeInfoNoPage(MessageNoticeBO messageNoticeBO) {
        messageNoticeBO = addMustData(messageNoticeBO);
        Wrapper<MessageNoticeDTO> wrapper = getBySelectNoticeInfo(messageNoticeBO);
        if (messageNoticeBO.getPageNo() == 0 && messageNoticeBO.getPageSize() == 0)
            return messageNoticeMapper.selectList(wrapper);
        return messageNoticeMapper.selectPage(new Page<>(messageNoticeBO.getPageNo(), messageNoticeBO.getPageSize()), wrapper);
    }

    private Wrapper<MessageNoticeDTO> getBySelectNoticeInfo(MessageNoticeBO messageNoticeBO) {
        Wrapper<MessageNoticeDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("deleted", 0);
        wrapper.eq("status", messageNoticeBO.getStatus());
        wrapper.eq("is_publish", messageNoticeBO.getIsPublish());
//        wrapper.orderBy("is_top", true);
        wrapper.orderBy("sort", true);//按顺序排列
//        wrapper.orderBy("update_time", false);//按更新时间排序
        //wrapper.orderBy("create_time", false);
        return wrapper;
    }

    /**
     * @return : boolean
     * @Author :chenyu.wang
     * @Description : 检查是否存在相同排序
     * @Date : 2021.02.23 10:26
     * @Param : [sort]
     **/
    private boolean checkSort(Integer sort) {
        Wrapper<MessageNoticeDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("type", 0)
                .eq("deleted", 0)
                .eq("sort", sort);
        MessageNoticeDTO selectOne = this.selectOne(wrapper);
        return selectOne == null;
    }

    /**
     * @return : void
     * @Author :chenyu.wang
     * @Description : 修改其它排序号
     * @Date : 2021.02.23 10:29
     * @Param : [sort]
     **/
    private void updateOtherSort(Integer sort) {
        Wrapper<MessageNoticeDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("type", 0)
                .eq("deleted", 0)
                .ge("sort", sort)
                .orderBy("sort", true);
        List<MessageNoticeDTO> list = this.selectList(wrapper);
        if (CustomizeUtil.listIsNull(list)) {
            return;
        }
        for (MessageNoticeDTO dto : list) {
            sort += 1;
            MessageNoticeDTO updateDto = new MessageNoticeDTO();
            updateDto.setId(dto.getId());
            updateDto.setSort(sort);
            this.updateById(updateDto);
        }
    }

    /**
     * @return : void
     * @Author :chenyu.wang
     * @Description : 替换序号
     * @Date : 2021.02.23 14:06
     * @Param : [sort]
     **/
    private void replaceSort(Integer sort, Integer sortA) {
        Wrapper<MessageNoticeDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("type", 0)
                .eq("deleted", 0)
                .eq("sort", sort);
        MessageNoticeDTO selectOne = this.selectOne(wrapper);
        if (selectOne != null) {
            MessageNoticeDTO updateDto = new MessageNoticeDTO();
            updateDto.setId(selectOne.getId());
            updateDto.setSort(sortA);
            this.updateById(updateDto);
        }
    }
}
